메뉴 바로가기 검색 및 카테고리 바로가기 본문 바로가기

한빛출판네트워크

IT/모바일

다시 보는 ‘루비 온 레일즈 굴려보기’

한빛미디어

|

2007-03-30

|

by HANBIT

13,426

제공: 한빛 네트워크
저자: Bill Walton, Curt Hibbs
역자: 추홍엽
원문: Rolling with Ruby on Rails Revisited

아마도 여러분은 웹 애플리케이션을 개발하는 무진장 생산성 있는 새로운 방법인 루비 온 레일즈에 대해 들어봤을 것이다. 그리고 한번 해보려고 시도는 해보지만 루비 온 레일즈에 대해 아는 게 없을런지 모른다.

그것이 바로 지금으로부터 거의 2년 전에 썼던 루비 온 레일즈 굴려보기(Rolling with Ruby on Rails)의 원래 버전이 시작된 계기이다. 루비 온 레일즈(줄여서 레일즈)는 엄청 생산적이고 엄청 재밌기도 했다! 기고가들의 커뮤니티는 더욱 생산적이고 더욱 재미있게 하기 위해 성장했다! 레일즈는 빨리 성장해왔다. 이것은 여러분들이 보고 믿어야 할 능력들을 가지고 있다!!! 그게 우리가 여기서 바라는 바다.

원래 버전처럼 이 튜토리얼은 루비 온 레일즈를 사용하여 웹 기반의 데이터베이스 주도형 애플리케이션을 개발하는 법을 보여줄 것이다. 또한 역시 원래 버전처럼 루비에서의 프로그래밍하는 법을 가르치지는 않을 것이다. 한편 이미 다른 객체지향 프로그래밍 언어를 접해본 경험이 있다면 따라오는데 아무 문제 없을 것이다. (그리고 마지막에는 루비와 그 외 여러가지 것들을 배울 수 있는 링크가 있다.)

시작하기 전에 몇몇 자주 묻는 질문에 대해 답변하려 한다.

루비란 무엇인가?

루비는 프로그래밍을 우아하고 즐겁게 만드는 매우 깔끔한 문법을 가진 객체지향 프로그래밍 언어이다. 루비는 성공적으로 스몰토크의 개념적인 우아함과, 파이썬의 사용과 습득의 용이성, 펄의 실용주의를 혼합했다. 루비는 1990년대 초 일본에서 시작되었다. 이것은 더 많은 영문 책과 문서들이 사용가능해짐에 따라 지난 몇 년간 전세계적으로 유명해졌다. (그리고 레일즈가 소개되면서 더욱 유명해졌다!)

레일즈란 무엇인가?

레일즈는 웹기반 데이터베이스 주도 애플리케이션을 개발하기 위한 오픈소스 루비 프레임워크이다. 레일즈가 뭐가 그리 특별할까? 루비와 관련된 프레임워크가 매우 많고 대부분 레일즈보다 오랫동안 사용되어 온 것들이다. 그런데 왜 아직도 또 다른 프레임워크에 대해 신경써야 할까?

필자가 만약 레일즈로 개발하는 것이 기존의 자바 프레임워크로 개발하는 것보다 최소 10배나 빨리 웹 애플리케이션을 개발 할 수 있다고 말하면 어떻게 생각할 것인가? 그렇게 할 수 있다. 애플리케이션의 품질을 떨어뜨리지 않고 말이다! 이게 어떻게 가능하다는 걸까?

대답의 일부는 루비 프로그램 언어에서 찾을 수 있다. 레일즈는 루비의 모든 이점을 가진다. 나머지 대답은 레일즈를 이끄는 두 가지 원칙이다. 즉 코드 줄이기(Less software)와 설정을 대체하는 규칙(Convention over configuration)이다.

코드 줄이기(Less software)는 애플리케이션을 구현하기 위해 더 적은 코드를 작성하는 것을 의미한다. 코드를 적게 유지하는 것은 개발을 더 빠르게 하고 버그가 더 적어지며, 그로 인해 코드가 더 이해하기 쉬워지고 유지보수하기 쉬워지고 강화하기 쉬워진다는 것을 의미한다. 아주 간단히, 레일즈가 어떻게 코드 부담을 잘라내는지 보게 될 것이다.

설정을 대체하는 규칙(Convention over configuration)은 XML 설정 파일에 대해 더 이상 과도하게 설명하지 않아도 되게 한다. 레일즈에서는 그러한 설정 파일들이 없다! 설정 파일 대신에 레일즈 애플리케이션은 반사와 발견을 통해 모든 것을 산출해 낼 수 있게 하는 약간의 간단한 프로그래밍 규칙을 사용한다. 애플리케이션 코드와 작동중인 데이터베이스는 이미 레일즈가 필요한 모든 정보를 담고 있다!

백문이불여일견

개발자들은 뭔가 새로운 것을 동반한 과도한 사기들을 많이 들어왔다. 우리도 안다. 우리도 역시 개발자다. 그래서 우리는 여러분들 얼굴에 떠 있는 미심쩍은 표정이 쉽게 상상이 간다. 엄청나게 생산적이라. 그렇다 정말 맞다!

여러분이 그것을 무조건 믿으라고 강요하진 않겠다. 여기서는 여러분 스스로가 풀어나가는 법을 보여줄 것이다.

이 튜토리얼을 다 읽고 나면, 여러분은 스스로 비슷한 결과들에 대해 흥미를 갖고 레일즈를 배울 준비가 되어 있을 것이다. 이 업데이트된 튜토리얼은 원본처럼 비슷해 보이고 똑같은 기능을 갖는 애플리케이션을 만들어 낼 것이다. 그래서 조금은 다른 방법으로 접근해 보려한다. 이것을 처음 해본다고 가정하지 말고, 점심시간 전에 팀장이 여러분의 사무실로 걸어들어와 다음과 같이 말한다고 가정해보자.

팀장: 이봐 CB(여러분의 이름이라고 가정해보자). 복잡한 일이 생겼네. 자네 도움이 필요해. 난 내일 아침 부장님께 조그만 쇼를 보여주기로 되어있었네. 부장님께 필요한 작은 애플리케이션을 만들어오고 있었거든. 그건 일종의 커다란 계약을 하기 위한 거고 내 생각엔 내일 아침 시연에 몇몇 사람들을 초대하실꺼 같아. 아마 윗분들이겠지. 문제는 내가 그걸 만들려고 외부 컨설턴트를 써오고 있었거든. 근데 그가 밤새 복권이라도 당첨됐는지 오늘 아침에 나타나질 않는거네. 이메일에도 응답없고 휴대전화도 받질 않아. 거기다 더욱 중요한 건 한 시간 전쯤 알 수 없는 이유로 애플리케이션이 멈춘거야 게다가 그 소스 코드는 찾을 수도 없고. CB, 난 내일 아침 부장님께 이런 얘기를 하고 싶진 않다네. 소문에는 자네가 새로운 개발 툴을 승인받으려 한다더군. 지금 사용하는 툴보다 10배 정도 빠르게 코드를 생산할 수 있다고 했다면서?

CB: 네. 루비 온 레일즈라 불리는 건데요. 최소 10배는 빠릅니다. 그러나 아직 본부 녀석들을 설득시키지 못해서요. 그들을 한번 쳐다보게도 하지 못했어요. 그들은 새로운 것들을 당장 접목해 보는 것에 대해 관심이 없는 것 같습니다.

팀장: CB, 난 정말로 내일 아침까지는 이 애플리케이션이 고쳐져야 하는 상황이야. 할 수 있다면 아무 툴이나 사용해도 괜찮아. 나에게 단지 우리 꼰대가 선보인 애플리케이션처럼 보이고 그렇게 작동하는 웹기반의 데이터베이스 주도 애플리케이션을 주기만 하면 되네. 작업량이 많다는 건 알아. 너무 늦게 부탁한 것도 같지만, 내일 아침에 어떻게 해서든 그걸 내놔야 돼. 그건 말해줄 수 있네. 만약 자네가 해준다고 동의한다면 내가 전화해서 본부 녀석들과 관계를 틀 수 있게 해주지.

CB: (기회라고 느끼며...) 팀장님, 이거 하나만 더요. 점심때가 거의 다 됐는데 팀장님이 피자 한판 쏘시고, 레일즈가 얼마나 생산적인지 보여드릴 수 있게 해주시면 점심시간 끝나기 전까지는 다 고칠 수 있을꺼에요.

팀장: 아니! 점심시간 끝날때까지? 그래 좋네, CB.

CB: 식은 죽 먹기죠. 피자나 사오세요. 레일즈 설치 좀 할께요. 본부 녀석들이 방화벽을 통해 레일즈 다운받는걸 허가 안해줘서 오늘 아침 CD를 가져왔거든요. 팀장님 돌아오실 때 쯤이면 준비되어 있을 껍니다.

팀장: 내가 돌아올 때 까지 새로운 개발 환경을 셋팅한다고? 그리고 나서 피자를 먹는 동안 아까 말했던 애플리케이션을 다시 만들어 낸다고? 아, 암것도 아닐쎄. 갔다와야겠군. 기분나빠하진 말게 하지만 믿기 힘들군. 하지만 물론 자네가 옳기를 바라고 있네.

이렇게 이야기는 시작된다. 팀장은 피자를 사러갔고 우리는 레일즈 설치를 서두를 필요가 있다.

레일즈 설치와 환경설정

이전 버전의 튜토리얼에서는 Curt가 Microsoft Windows 플랫폼 상에서 레일즈를 설치하고 설정하는 법을 보여줬었다. 이번 튜토리얼을 준비하면서는 이번에 이것을 어떻게 다룰까에 대해 토의했다. 똑같은 내용을 다시 할 수는 있었지만 여러 환경 중 한가지 환경(특히 Windows!)를 선호하는 것에 대해 약간의 불평들이 있었다. 이것에 대한 대안으로 윈도우, 맥, 리눅스 모두에서 레일즈를 설치하고 설정하는 법을 보여줄 수도 있었지만, 이는 각각에 대해 많은 지면을 할애해야 할 것이다. 또 다른 대안으로 우리는 다음과 같은 이점을 가지고 있는데, 원래의 튜토리얼 이래로 나온 새로운 툴들은 이러한 각각의 환경에 대해 설치하는 법과 환경설정에 대한 스냅샷을 만들어 뒀다는 것이 그것이다. 우리는 단지 이 자료들만 짚어준다. 이 마지막 방법이 편애에 대한 태클을 피하고 더 적은 노력을 들일 수 있기에... 뭐 어쨌든, 우린 단지 "작동가능한 가장 간단한 것"을 하고 있을 뿐이다.

윈도우 사용자는 Instant Rails를 사용하라.

맥OS X 사용자는 Locomotive를 사용하라.

리눅스 사용자는 Rails LiveCD를 시도해본다.

이것들 중 어떤 것이라도 피자가 도착하기까지 걸리는 시간보다 더 빨리 첫 번째 레일즈 애플리케이션 개발을 시작할 수 있게 해줄 것이다.

피자 도착!

팀장: 좋아, CB. 피자 여깄네. 이제 자네의 새로운 툴이 얼마나 멋진지 보기로 했었지, 그러나 나는 "어떻게 작동하는지"등에 대해 자세히 이해할 필요가 없네, 그래서 폴을 데려왔지. 그것을 부가적으로 여기는데에 대해 상관 안한다면 나는 자네 둘이 자세한 내용을 약간 파고들어도 신경쓰지 않겠네. 괜찮나?

CB: 물론이죠. 안녕하세요 폴. 일단 피자 한조각 뜨고 시작하죠! 팀장님은 이전에 작업해 오시던 애플리케이션처럼 보이는 걸 원하시는 거죠. 그러나 그 애플리케이션은 지금 고장났구요. 작업하던거 보여주실꺼 있으십니까?

팀장: 컨설턴트의 책상에서 메인 화면(그림1)에 대한 이 사진을 발견했네.


[그림1] 우리의 목표!

기본적으로 이 애플리케이션은 다음 세가지를 수행할 수 있게 되어 있지.
  • 모든 레시피의 리스트를 보여줌.
  • 새로운 레시피를 만들거나 기존의 레시피를 수정.
  • 레시피를 카테고리에 할당. ("디저트"나 "스프"와 같이)
여기 애플리케이션이 어떻게 작동하는가에 대한 세부사항이 적힌 노트도 같이 발견했네.

요구되는 기능
  • 제목 - 모든 페이지 동일.
  • 소제목 - 모든 페이지 동일.
    • 레시피 - 클릭하면 편집할 수 없는 화면의 레시피들을 보여주는 페이지로 이동. 그 페이지는 레시피를 편집 및 저장할 수 있는 링크와 리스트 페이지로 돌아올 수 있는 링크를 가짐.
    • (삭제) - 클릭시 레시피를 데이터베이스로부터 삭제하고 화면에서도 제거함.
    • 카테고리 - 클릭시 해당 카테고리에 포함된 레시피만 보여줌.
    • 날짜 - 레시피가 생성되거나 수정되었을 때 시스템에 의해 날짜가 부여되어야 함.
  • 꼬리말 - 모든 페이지에서 보임. 노트: 카테고리 페이지에서 좌측의 링크는 "새 카테고리 생성"이 됨. 이것은 "새 레시피 생성" 링크와 유사하게 작동해야 함. 꼬릿말의 나머지는 모든 페이지 동일.
    • 새 레시피 작성 - 클릭하면 레시피 이름, 설명, 절차와 어느 카테고리로 할당할 것인지 선택할 수 있는 폼으로 이동.
    • 모든 레시피 보기 - 클릭하면 모든 레시피 표시로 이동. 카테고리 링크 중 하나를 클릭해서 필터링 된 리스트에서 원래대로 돌아올 때 사용.
    • 모든 카테고리 보기 - 클릭시 기존 카테고리들을 편집하고 삭제할 수 있는 페이지로 가는 링크들을 위한 뷰페이지로 이동 (꼬릿말은 "새 카테고리 생성"링크를 가짐)
이게 우리가 해야 할 전부네.

코드를 작성해보자!

CB: 좋아요 그럼. 시작해보죠. 레일즈로 가능한 것들 중 하나는 순환적이고 점증적으로 개발에 접근할 수 있다는 겁니다. 아주 잠깐 보게 되겠지만, 레일즈는 적은 노력으로 많은 것을 가져다 주기 때문에 그런 리듬에 빠지지 않기가 힘들어요. 보통, 레일즈 애플리케이션을 개발할 때마다 같은 단계를 밟습니다.
  1. 빈 레일즈 애플리케이션을 생성한다.
  2. 레일즈가 선택할 기본 데이터베이스 명을 사용 할 것인지, 레일즈에게 애플리케이션에 사용할 데이터베이스를 가르쳐 줄 것인지를 결정한다.
  3. 애플리케이션에 사용할 데이터베이스가 존재하지 않는다면 새로 생성한다.
  4. 어떤 기능이 작동할 것인지를 결정한다.
  5. 그 기능을 만드는데 사용할 테이블이 없다면 새로 생성한다.
  6. 테이블을 사용하는 것을 기반으로 하는 코드를 생성한다.
  7. 세부조정을 한다.
  8. 완성할 때까지 4단계에서 7단계를 반복한다.
이것들이 제가 보여드릴 단계들입니다.

빈 레일즈 웹 애플리케이션 생성

CB: 레일즈는 애플리케이션 개발 프레임워크입니다. 이것이 의미하는 것 중 하나는 모든 레일즈 애플리케이션마다 기본 구조가 같다는 거죠. 레일즈는 새 애플리케이션을 빌드하려 할 때 그 구조를 생성해 줌으로써 그러한 컨벤션을 쉽게 따를 수 있게 합니다. 우리가 해야 할 전부는 단지...

커맨드창을 열고 애플리케이션을 만들 위치로 이동합니다. 여기를 레일즈 루트 디렉토리라 부르구요. 그 이름은 사용하는 OS에 따라 달라질 수 있지만, 그 하위에 위치하는 디렉토리들의 이름과 구조는 동일합니다. 그러니깐 이제부터 제가 말하는 경로는 레일즈 루트의 일부라고 가정할껍니다.

그럼 이제 이걸 뭐라고 부르고 싶으시죠?

팀장: 첫 번째 녀석은 cookbook 애플리케이션이라고 불렀다네.

CB: 좋습니다. 이건 cookbook2라고 부르죠.

빈 애플리케이션을 생성하기 위해 단지 명령만 하나 실행시켰습니다.

rails cookbook2

레일즈는 빈 레일즈 애플리케이션을 위해 폴더와 파일 등 완전한 디렉토리 구조를 갖춘 cookbook2 서브 디렉토리(레일즈 루트 디렉토리 아래에 있는)를 생성합니다. (그림 2)


[그림 2] 새 애플리케이션 디렉토리 생성 작업중인 레일즈

Paul: 이 디렉토리 구조에 대해 좀 더 알려주세요 CB. 몇 무더기의 디렉토리들이 보이는데 저걸 다 작성해야 하나요?

CB: 레일즈가 거의 다 알아서 만들어 줍니다. 대부분의 우리 애플리케이션 서브 디렉토리들을 제외하면 말이죠. 레일즈 애플리케이션들은 소스 코드를 조직화 하는데 있어서 모델-뷰-컨트롤러(MVC) 패러다임을 사용합니다.
  • app/controllers 디렉토리는 레일즈가 컨트롤러 클래스들을 찾기 위해 살펴보는 곳이다. 컨트롤러는 사용자로부터 웹 요청을 다룬다.
  • app/views 디렉토리는 애플리케이션으로부터 데이터를 채워넣은 템플릿들을 담고 있는데, 이것들은 HTML로 변환되어 사용자의 브라우저로 보내진다.
  • app/models 디렉토리는 애플리케이션의 데이터베이스에 저장된 데이터들을 모델링하고 감싸는 클래스들을 담는다. 대부분의 프레임워크에서는 애플리케이션의 이러한 모델 부분이 매우 산만하고, 지겹고, 장황하고, 에러가 발생하기 쉬워질 수 있다. 레일즈는 이걸 죽여주게 간단하게 만든다!
  • app/helpers 디렉토리는 모델, 뷰, 컨트롤러 클래스들을 보조하는데 사용하는 헬퍼 클래스들을 담는다. 이러한 헬퍼 클래스들은 모델, 뷰, 컨트롤러 코드들을 작고 집중되고 정리가 잘 되어 있게 만든다.
레일즈 애플리케이션은 하나의 애플리케이션이지, 약간의 스크립트가 추가된 거의 정적인 페이지들의 모음이 아니라는 사실을 기억하는 것이 중요합니다. 레일즈 애플리케이션은 자신이 사용하는 웹 페이지들을 생성합니다. 그러므로 레일즈에서 컨트롤러가 어떻게 작동하는지, 그리고 URL이 컨트롤러 메소드와 어떻게 매핑되는지(그리고 실행되는지)를 이해하는 것이 중요합니다.

컨트롤러 클래스들은 웹 요청을 다룹니다. 방문자의 요청 URL은 컨트롤러 클래스와 클래스 내의 메소드에 매핑됩니다. 정적인 웹페이지에 매핑되는게 아니구요. 방문자가 브라우저에 레일즈 애플리케이션 URL을 입력하여 요청-응답 주기를 시작하면 애플리케이션의 컨트롤러가 호출되고, 모델을 사용하여 임의의 데이터를 가져오거나 저장하고, 뷰를 사용하여 방문자의 브라우저로 보낼 HTML을 생성합니다.

애플리케이션의 하위 디렉토리에 있는 파일들 뿐만 아니라, 다른 디렉토리에도 우리가 만들고 수정할 여러 파일들이 있습니다. 곧 이것도 시작할 것이지만, 우리의 작업의 대부분은 app/ 의 하위 디렉토리에서 파일들을 생성하고 편집하게 될 겁니다.

레일즈에게 애플리케이션에서 사용할 데이터베이스를 알려주기

CB: 이제 빈 레일즈 애플리케이션을 다 만들었구요, 어떤 데이터베이스를 쓸 것 인지를 알 필요가 있습니다. 레일즈 규칙에서 개발 중에 사용하는 데이터베이스명은 애플리케이션명(이 경우에는 cookbook2)에 _development를 붙여서 사용합니다. 제 생각엔 그게 좋은거 같아요. 우리의 데이터베이스 이름은 cookbook2_development로 하겠습니다. 그리고 개발 데이터베이스의 패스워드는 비워놓겠습니다. 그게 레일즈가 데이터베이스 설정 파일을 생성할 때 사용하는 규칙이거든요. 만약 패스워드를 설정하면, 데이터베이스에 접근할 때 패스워드를 레일즈에게 알려줘야 하겠죠. 데이터베이스 명을 바꾸고 싶거나 패스워드를 바꾸고 싶다면 ..cookbook2configdatabase.yml 파일을 수정하면 됩니다. 그 파일을 보면 우리가 바꾸고 싶은 부분이 매우 확실하게 보일 겁니다. 팀장님에게 조차 말이죠. (그는 폴에게 윙크하며 말했다.) 지금은 레일즈 컨벤션을 잘 지켰기 때문에 설정을 조금도 바꾸지 않아도 됩니다.

애플리케이션이 사용할 데이터베이스를 생성하기

CB: 이제 cookbook2_development 데이터베이스를 만들 필요가 있습니다. 팀장님이 지금까지 제가 말한 것을 어떻게 들으셨는지는 모르겠지만, 저는 기존의 툴에 레일즈를 교체하여 끼워넣고 있는 게 아니라는 것을 확실히 해두고 싶군요. 레일즈의 가장 핵심은 데이터베이스 주도로 구축해 가는 웹기반 애플리케이션이라는 겁니다. 토스터보고 커피포트에게 말을 걸라고 하기 위한 게 아니라는 거죠. 그런거라면 레일즈 보다 좋은 플랫폼들이 존재합니다. 사실..

Paul: CB, 지금 당장은 그 얘기를 할 때가 아닌 것 같군요.

CB: 맞아요, 폴. 죄송하게 됐습니다.

우리의 레일즈 애플리케이션은 데이터베이스가 필요합니다. MySQL 엔진이 작동중인 것을 확인했습니다. 아까 열었던 커맨드창에서 루트 권한으로 로그인 하겠습니다.

$ mysql -u root -p

이 데이터베이스에서 아무것도 설정하지 않았기 때문에 패스워드 프롬프트에서 그냥 엔터를 치면 됩니다.

그리고 나면 데이터베이스를 생성합니다:

create database cookbook2_development;

(노트: 마지막에 세미콜론이 필요함.)

윈도우에서 작업하고 있으므로 ODBC란 이름의 사용자에게 데이터베이스 접근권한을 줄 필요가 있습니다. 그렇게 하지 않으면 커맨드 창에서 데이터베이스로 접근하려 할 때, MySQL로 부터 에러가 날껍니다. 접근을 허가하려면 단지 이렇게만 입력하면 됩니다:

grant all on cookbook2_development.* to "ODBC"@"localhost";

노트: 윈도우 환경에서 작업하는 것이 아니라면 (혹은 윈도우라 하더라도 몇몇 경우에는) 이러한 승인이 필요하지 않을 수 있다. 보통 일반적인 사용자에게 데이터베이스에 대한 무한한 권한을 허가하는 것은 흔치 않은 일이다. 이 튜토리얼을 따라하는 동안 쉽게 피할 수 있는 문제를 맞이하게 하지 않기 위해 이렇게 언급해둔다.

됐습니다. 이제 MySQL에 대한 작업은 끝났으므로 요렇게...

exit

... 입력하고 운영체제로 돌아옵니다. (그림 3).


[그림 3] CB는 윈도우상에서 레일즈 애플리케이션에 사용할 MySQL 데이터 베이스를 생성한다.

작동할 기능 결정하기

CB: 좋습니다 팀장님. 저에게 주셨던 스크린샷은 레시피를 생성하고 읽고, 업데이트하고 삭제할 수 있다는 것을 보여주는 군요. 주셨던 컨설턴트의 노트에서는 같은 것을 카테고리에도 할 수 있고, 각 레시피는 단일 카테고리에 속한다는 것을 알 수 있습니다. 전반적으로 아주 직관적입니다. 어디부터 시작해야한다고 생각하시죠? (CB는 혼자 싱긋 웃으며 물었다. 팀장에게 큰소리 치는게 즐거운가보다.)

팀장: 음, CB (조금은 겸손하게 말한다.), 내 생각엔 하나의 레시피를 만드는 걸로 시작하는게 나을 듯 한데, 맞나? 그러고나면 읽기로 이동하고, 그 후엔 수정하기로, 그 후엔 삭제하기. 그러고나면 같은 것을 카테고리에 대해서도 할 필요가 있지, 그리고는 그것들을 서로 연결할 필요가 있겠네. 최종적으로는 실제 코딩에 착수하는 거지. 그게 보통 우리가 이런 것들을 할 때 쓰는 방법 아닌가?

CB: 네. 그게 보통 우리가 하는 방법이죠, 팀장님. (그것봐! ;-) ) 하고 또 하고 또 반복하죠. 그리고 그것이 레일즈의 요점입니다. 우리는 데이터베이스 주도 애플리케이션을 개발할때 매번 이와 똑같은 것들을 하려 합니다. 그걸 자동화시키고 실제 작업에 착수해보죠. 레일즈는 우리가 사용하려는 데이터를 생성하고, 읽고, 갱신하고, 삭제할 필요가 있다고 가정합니다. 일단 작업할 수 있는 테이블이 만들어지면, 레일즈는 우리가 그렇게 만들 필요가 있는 모든 기본 코드를 생성해 낼 겁니다. 이건 우리가 보통 하던것 보다 더 크게 한 입 물 수 있다는 것을 의미하죠. 그것이 바로 10배의 생산성을 가져올 수 있는 이유입니다.

이 애플리케이션은 레일즈에게는 정말 무지 단순한 거에요. 사실, 이건 레일즈의 "중심점"에 있다고 하는 게 맞습니다. 그럼 한 입 베물어 보도록 하죠.

애플리케이션이 해당 기능을 사용할 수 있는 테이블을 생성하기

CB: 레시피를 위한 테이블이 하나 필요하고 카테고리를 위한 테이블이 또 하나 필요하다는 것은 명백합니다. 그 둘 사이의 관계는 카테고리에서 레시피로 일 대 다(one-to-many) 관계입니다. 이것은 레시피 테이블에 외래키 필드를 포함할 필요가 있다는 것을 의미합니다.

그것을 생성하기 위해 텍스트 에디터를 하나 열고 몇 줄의 SQL 스크립트를 작성하겠습니다.
drop table if exists recipes;
drop table if exists categories;
create table categories (
    id                     int            not null auto_increment,
    name                   varchar(100)   not null default "",
    primary key(id)
) engine=InnoDB;

create table recipes (
    id                     int            not null auto_increment,
    category_id            int            not null,
    title                  varchar(100)   not null default "",
    description            varchar(255)   null,
    date                   date           null,
    instructions           text           null,
    constraint fk_recipes_categories foreign key (category_id) references categories(id),
    primary key(id)
) engine=InnoDB;
CB: 이봐요, 폴. 우리가 작업했던 애플리케이션 디렉토리 외부에 몇개의 파일들이 있던 것을 기억해요? 애플리케이션이 사용할 테이블을 생성하는 SQL 스크립트가 그 파일들 중 하나입니다. 그래서 팀장님. 이제 ..cookbook2dbcreate.sql로 파일을 저장하고 테이블을 생성할 준비가 됐습니다.

열려 있는 커맨드 창에서 cookbook2 디렉토리로 이동합니다. cookbook2 디렉토리에 있는지 확인하고 이렇게 입력합니다:

mysql cookbook2_development
MySQL은 스크립트를 실행하고 아무런 표시없이 커맨드 라인으로 돌아옵니다. 이것은 모든 것이 잘 됐다는 것을 의미하죠. 우리의 데이터베이스는 이제 두개의 빈 테이블을 가지고 있습니다. 레시피와 카테고리 테이블이요.

Paul: CB, 그 스크립트는 MySQL에 특정지어져 보이는데, 그게 본부 녀석들에게는 문제가 될 수 있어요.

CB: 알아요. SQL 스크립트의 또 다른 부정적인 면은 테이블에 임의의 필드를 추가할 필요가 있다고 결정했을 때 데이터를 잃는다는 겁니다. 스크립트에 대한 긍정적인 면은 정말 쉽다는 거구요. 그게 바로 여기서 팀장님과 함께 SQL을 사용하는 이유입니다.

운좋게도 레일즈는 마이그레이션이라는 툴 역시 제공합니다. 지금 당장 하기에는 다소 규모가 크지만, 마이그레이션은 데이터베이스 플랫폼의 독립성을 주고, 데이터 변경시 손실없이 점진적으로 모델 상에서 작업할 수 있게 해주는 메커니즘을 제공합니다. 아마 나중에 거기에 대해 더 얘기할 수 있는 기회가 있을 겁니다.

테이블을 사용하기 위한 코드 기반 생성하기

CB: 이제 레일즈가 다룰 수 있는 테이블을 갖추고, 우리의 기본 애플리케이션을 생성하게 합니다. 레일즈 전문용어로 이것을 스캐폴딩(scaffolding)이라고 하는데요. 커맨드 창에서 현재 cookbook2 디렉토리에 있는지를 다시 한번 확인하고 이렇게 입력합니다:

ruby scriptgenerate scaffold recipe recipe

이것은 레일즈에게 스캐폴딩을 생성하라고 말합니다: 레시피 테이블을 사용할 애플리케이션의 일부를 위한 기본적인 모델, 컨트롤러, 뷰 파일들 말이죠. 레일즈가 꽤 되는 몇개의 파일을 생성하는 것을 볼 수 있습니다. (그림 4). 명령 줄에서 저는 단지 레일즈에게 특정한 두 파일에 대해서만 알려줬습니다. 모델(첫번째 인자)과 컨트롤러(두번째 인자)죠. 레일즈는 모델 파일을 recipe.rb라 이름짓고 ..cookbook2appmodels의 하위 디렉토리에 위치시킵니다. 이와 유사하게, 컨트롤러는 recipe_controller.rb라 이름짓고 ..cookbook2appcontrollers 하위 디렉토리에 위치시킵니다.


[그림 4] 레시피 스캐폴딩 코드 생성

이제 카테고리에 대해서도 같은 작업을 합니다. 다시 한번 커맨드 창에서 이렇게 입력합니다:

ruby scriptgenerate scaffold category category

이것은 레일즈에게 Categories 테이블을 사용하는 애플리케이션 부분에 대한 기본적인 모델, 컨트롤러, 뷰 파일들(그림 5)을 생성하게 합니다. 앞에서 처럼 레일즈는 모델 파일을 ..cookbook2appmodelscategory.rb로 저장하고 컨트롤러 파일을 ..cookbook2appcontrollerscategory_controller.rb로 저장합니다.


[그림 5] 카테고리 스캐폴딩 코드 생성

CB: 좋습니다. 지금 시점까지 해온 모든 것들은 꽤 짧고 무난했죠 그러나 특별히 흥미롭지는 않았습니다. 이제 변화를 줄 때입니다.

하지만 더 진행하기 전에 지금까지 한것이 정확히 무엇인지를 살펴보죠. 저는 모두 여덟 라인의 명령을 입력했었습니다. MySQL 명령 다섯개와 레일즈 명령 세개였죠. 빈 줄없는 17라인짜리 SQL 스크립트를 만들었구요. 이것들은 제가 아직 코딩이라 부를 수 없는 것들입니다. 하지만 이제 막 보게 될 껀데요... 자... 모자 꽉 잡으세요!

성능향상

CB: 애플리케이션을 실행하기 위해 Mongrel이라는 웹서버를 사용하겠습니다. 시작하기 위해 커맨드창의 cookbook2 하위 디렉토리에서 이렇게 입력합니다:

mongrel_rails start

Mongrel 시작이 끝나면 애플리케이션을 실행할 준비가 된겁니다.


[그림 6] 웹서버 시작

CB: 준비 됐나요?

팀장: 뭘 준비해? 자넨 방금 나에게 아직 아무 코드도 작성하지 않았다고 상기시켜 주지 않았나.

CB: 맞습니다. 그러나 그 말이 생산적이 아니라는 것을 의미하지는 않습니다. 여기 키보드를 잡으세요. 이제 브라우저 창을 열고 http://localhost:3000/category에 접속해보세요(그림 7).

Paul: 저는 Mongrel에 대해선 들어본 적이 없는데요, 레일즈 애플리케이션은 그것을 이용해야만 합니까?

CB: 전혀요. Mongrel은 매우 가볍고 매우 레일즈와 친화적인 웹서버입니다. 개발중에 로컬로 애플리케이션을 수행하는데 있어서는 정말 대단하죠. 그리고 그것은 많은 생산 환경에서도 사용됩니다. 그러나 "반드시 사용해야" 하는 것은 아니에요. 몇몇 다른 대안이 있는데 원하시면 나중에 다시 얘기 하도록 하죠.


[그림 7] 첫번째 레일즈 애플리케이션

링크를 클릭하세요 (그림 8).


[그림 8] 새 카테고리 입력 페이지

카테고리 이름을 입력하고 "생성" 버튼을 눌러보세요 (그림 9).

노트: 눈치빠른 독자들은 CB가 여기서 "레시피를 입력하고 "생성" 버튼을 클릭하라"고 말하지 않았다는 것을 알아챘을 것이다. 왜냐고 물어볼 수 있는데, 그건 아마 아직 작동하지 않을 것이다. 우린 아직 아무 코드도 작성하지 않았음을 기억하라. 여기서는 많이 쓰지는 않을 것이다. 그러나 모두 함께 끌어들이기 위해 몇 줄은 더 필요하다. 많지는 않고 조금만. 현재 이 기사의 두번째 파트가 이용가능하다.


[그림 9] 새 카테고리 추가

팀장: 이거 시원시원한 방법 정도가 아닌데 그래-- 정말 대단한걸! 레시피에 대해서는 어떤가?

CB: 그냥 http://localhost:3000/recipe로 접속하기만 해보세요. (그림 10).


[그림 10] 빈 레시피 목록.

링크를 클릭해보세요 (그림 11).


[그림 11] 새 레시피 입력 페이지

CB: 팀장님 모자 어디 갔어요? 날아간게 분명하군요! 꼭 잡고 계시라고 했었는데!

팀장: 이거 놀랍기만 하군 그래, CB. 사실대로 말하지. 내가 피자를 사오겠다고 했을 때, 난 정말 자네가 실제로 이 애플리케이션을 만들 수 있을거라고 믿지 않았었네. 그것도 점심시간이 끝나기 전까지 완료할거라곤. 자네가 나에게 거짓말하진 않았을꺼란 느낌이 들기 시작하고 있네.

CB: 그리고 우린 아직 아무런 코드조차 작성하지 않았다는 거죠! 팀장님은 거기에 대해 아마도 불안해 하실지도 모릅니다만, 작성하기 전에 피자 좀 먹도록 하죠. 아시겠지만 레일즈 덕분에, 피자도 먹을 수 있는겁니다!


Bill Walton은 소프트웨어 개발/프로젝트 관리에 대한 컨설턴트이자 사업자이다.
Curt Hibbs는 항상 새로운 테크놀로지와 기술 트렌드 추적에 사로잡혀 있다.
TAG :
댓글 입력
자료실

최근 본 책0